/*---------------------------------------------------------------------------
//
//	Copyright(C) SMIT Corporation, 2000-2010.
//
//  File	:	smcam_trace.cpp
//	Purpose	:	trace macro - common
//	History :
//				2004-09-10 created by pmy.
//
---------------------------------------------------------------------------*/

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include "sm_types.h"
#include "sm_trace.h"


#define DEBUG_BUF_SIZE	4096
static int	s_modLevels[TRMOD_COUNT] = 
{
	TRLEV_ERROR, //越高级别输出的调试信息越多
	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,

	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,
		
	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,
	TRLEV_ERROR,
};


unsigned long sm_trace_set_level(unsigned long mod, unsigned long level)
{
	//mod为模块ID, level为调试级别
	if (mod >= TRMOD_COUNT)
	{
		SM_Printf("sm_trace_set_level() - trace_mod_id=%d is invalid\r\n", mod);
		return -1;
	}
	s_modLevels[mod] = (int)level;
	SM_Printf("sm_trace_set_level() - set_trace, mod=%d, level=%d\r\n", mod, level);
	return OK;
}


void diag_printf_speclev(unsigned long mod, unsigned long level, const char *fmt, ...)
{
	va_list	va;
	char	szBuffer[DEBUG_BUF_SIZE];	
	if (mod < TRMOD_COUNT && s_modLevels[mod] >= (int)level)
	{
		va_start(va, fmt);
		vsnprintf(szBuffer, sizeof(szBuffer), fmt, va);
		va_end(va);
		SM_Printf("%s", szBuffer);
	}
}


void diag_printf_critical(unsigned long mod, const char *fmt, ...)
{
	va_list	va;
	char	szBuffer[DEBUG_BUF_SIZE];	
	if (mod < TRMOD_COUNT && s_modLevels[mod] >= TRLEV_CRITICAL)
	{
		va_start(va, fmt);
		vsnprintf(szBuffer, sizeof(szBuffer), fmt, va);
		va_end(va);
		SM_Printf("%s", szBuffer);
	}
}


void diag_printf_error(unsigned long mod, const char *fmt, ...)
{
	va_list	va;
	char	szBuffer[DEBUG_BUF_SIZE];	
	if (mod < TRMOD_COUNT && s_modLevels[mod] >= TRLEV_ERROR)
	{
		va_start(va, fmt);
		vsnprintf(szBuffer, sizeof(szBuffer), fmt, va);
		va_end(va);
		SM_Printf("%s", szBuffer);
	}
}


void diag_printf_notify(unsigned long mod, const char *fmt, ...)
{
	va_list	va;
	char	szBuffer[DEBUG_BUF_SIZE];	
	if (mod < TRMOD_COUNT && s_modLevels[mod] >= TRLEV_NOTIFY)
	{
		va_start(va, fmt);
		vsnprintf(szBuffer, sizeof(szBuffer), fmt, va);
		va_end(va);
		SM_Printf("%s", szBuffer);
	}
}


void diag_printf_info(unsigned long mod, const char *fmt, ...)
{
	va_list	va;
	char	szBuffer[DEBUG_BUF_SIZE];	
	if (mod < TRMOD_COUNT && s_modLevels[mod] >= TRLEV_INFO)
	{
		va_start(va, fmt);
		vsnprintf(szBuffer, sizeof(szBuffer), fmt, va);
		va_end(va);
		SM_Printf("%s", szBuffer);
	}
}


void diag_printf_call(unsigned long mod, const char *fmt, ...)
{
	va_list	va;
	char	szBuffer[DEBUG_BUF_SIZE];	
	if (mod < TRMOD_COUNT && s_modLevels[mod] >= TRLEV_CALL)
	{
		va_start(va, fmt);
		vsnprintf(szBuffer, sizeof(szBuffer), fmt, va);
		va_end(va);
		SM_Printf("%s", szBuffer);
	}
}


void vdiag_printf_bytes(const unsigned char* buf, unsigned long size, 
					 const char *fmt, va_list valist)
{
	unsigned char	ch;
	char			sbHex[4];
	char			sbBuf[DEBUG_BUF_SIZE];
	unsigned char*	pbSrc = (unsigned char*)buf;	
	int				len= 0 ;
	int i = 0;

	len = vsnprintf(sbBuf, DEBUG_BUF_SIZE - 1, fmt, valist);
	if (-1 == len)
	{
		len = DEBUG_BUF_SIZE - 1;
	}
	sbBuf[len] = '\0';
	SM_Printf("%s[%d] ", sbBuf, size);
/*
	sbHex[2] = ' ';
	sbHex[3] = '\0';	

	while(size-- > 0)
	{
		ch = (*pbSrc);
		ch = (ch>>4)&0x0F;
		if (ch <= 9 )
			sbHex[0] = '0' + ch;
		else
			sbHex[0] = 'A' + ch - 10;

		ch = (*pbSrc);
		ch &= 0xF;
		if (ch <= 9 )
			sbHex[1] = '0' + ch;
		else
			sbHex[1] = 'A' + ch - 10;

		pbSrc++;
		SM_Printf("%s", sbHex);
	}
	SM_Printf("\r\n");
*/
	memset(sbBuf, 0, sizeof(sbBuf));
	while(size-- > 0)
	{
		ch = (*pbSrc);
		ch = (ch>>4)&0x0F;
		if (ch <= 9 )
			sbBuf[i++] = '0' + ch;
		else
			sbBuf[i++] = 'A' + ch - 10;

		ch = (*pbSrc);
		ch &= 0xF;
		if (ch <= 9 )
			sbBuf[i++] = '0' + ch;
		else
			sbBuf[i++] = 'A' + ch - 10;

		sbBuf[i++] = ' ';
		pbSrc++;
	}
	SM_Printf("%s", sbBuf);
}


void diag_printf_bytes_speclev(unsigned long mod, unsigned long level, 
							   const unsigned char* buf, unsigned long size,
								const char *fmt, ...)
{
	va_list	va;

	if (mod < TRMOD_COUNT && s_modLevels[mod] >= (int)level)
	{
		va_start(va, fmt);
		vdiag_printf_bytes(buf, size, fmt, va);
		va_end(va);
	}
}


void diag_printf_bytes(const unsigned char* buf, unsigned long size, const char *fmt, ...)
{
	va_list	va;

	va_start(va, fmt);
	vdiag_printf_bytes(buf, size, fmt, va);
	va_end(va);
}

void SM_GetCIBOXVersion(unsigned char* o_version)
{
	char 	buildtag[]="SMIT-CIBOX-01.04.00 Build on "__DATE__" at "__TIME__;
	char*	monstr[12]={"Jan","Feb","Mar","Apr","May","Jun",
						"Jul","Aug","Sep","Oct","Nov","Dec"};
	char	buildDate[30] = __DATE__;
	char	buildTime[30] = __TIME__;
	int		year=0,mon=0,day=0;
	int		hour=0,min=0;
	int		i;
	char*	ptr;
	char*	ptrMark;
	
	ptr = buildtag; //only for compiler 
	
	ptr = buildDate;
	ptrMark = strchr(ptr, ' ');
	if (!ptrMark)
		return;
	*ptrMark = 0;
	for (i = 0; i < 12; i++)
	{
		if (strcmp(ptr,monstr[i]) == 0)
			break;
	}
	mon = i + 1;
	
	ptr = ptrMark+1;
	while (*ptr == 0x20) ptr++;
	ptrMark = strchr(ptr, ' ');
	if (!ptrMark)
		return;
	*ptrMark = 0;		
	day = atoi(ptr);

	ptr = ptrMark+1;
	year = atoi(ptr);

	ptr = buildTime;
	ptrMark = strchr(ptr, ':');
	if (!ptrMark)
		return;
	*ptrMark = 0;
	hour = atoi(ptr);

	ptr = ptrMark+1;
	ptrMark = strchr(ptr, ':');
	if (!ptrMark)
		return;
	*ptrMark = 0;	
	min = atoi(ptr);

	sprintf(o_version, "SMIT CIBOX 01.04.00-%04d%02d%02d%02d%02d",year,mon,day,hour,min);
}
